package com.cah.project.plugs.aware;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.cah.project.plugs.IPlugsSlot;
import com.cah.project.plugs.PlugsModel;
import com.cah.project.plugs.annotation.PlugsSlot;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 功能描述: 插件扫描注册类 <br/>
 */
@Component
public class PlusAware implements ApplicationContextAware {

    private final Map<String, List<PlugsModel>> plugsMap = new HashMap<>();

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        PlusAware.applicationContext = applicationContext;
        Map<String, IPlugsSlot> beanMap = applicationContext.getBeansOfType(IPlugsSlot.class);
        Set<Map.Entry<String, IPlugsSlot>> entries = beanMap.entrySet();
        if(CollUtil.isNotEmpty(entries)) {
            List<PlugsModel> list = new ArrayList<>(beanMap.size());
            for (Map.Entry<String, IPlugsSlot> entry : entries) {
                // 获取注解
                PlugsSlot annotation = entry.getValue().getClass().getAnnotation(PlugsSlot.class);
                PlugsModel pm = new PlugsModel();
                pm.setPlugsSlot(entry.getValue());
                pm.setGroup(entry.getValue().getClass().getPackage().getName());
                if(annotation == null) {
                    pm.setOrder(0F);
                } else {
                    String group = annotation.group();
                    if(StrUtil.isNotBlank(group)) {
                        // 如果组别为空，则默认为包名。使代码分包规范，不会乱跑。使用时，随便指定一个类获取包名即可
                        pm.setGroup(group);
                    }
                    pm.setOrder(annotation.order());
                }
                list.add(pm);
            }
            // 最终排序后，添加到map中
            plugsMap.putAll(list.stream()
                    .sorted(Comparator.comparing(PlugsModel::getOrder))
                    .collect(Collectors.groupingBy(PlugsModel::getGroup)));
        }
    }

    public static PlusAware getPlusAware() {
        return applicationContext.getBean(PlusAware.class);
    }

    public List<PlugsModel> getPlugsModel(String group) {
        return plugsMap.getOrDefault(group, new ArrayList<>());
    }

}
